/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2008 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;

using Gtk;
using Glade;

using Anculus.Core;
using Anculus.Gui;

using Galaxium.Core;
using Galaxium.Protocol;
using Galaxium.Protocol.Gui;
using Galaxium.Gui;

namespace Galaxium.Gui.GtkGui
{
	// Here are various positions you can place widgets into.
	public enum ChatWidgetPositions { Identification, LeftView, RightView, 
		TopDisplay, BottomDisplay, LeftDisplayPane, RightDisplayPane, LeftInput, 
		RightInput, MessageEntry, EntryToolbar, LeftStatus, CenterStatus, RightStatus };
	
	public abstract class AbstractChatWidget : IChatWidget<Widget>
	{
		public event EventHandler BecomingActive;
		public event EventHandler BecomeActive;
		
		[Widget("ContentBox")]
		protected Gtk.VBox _contentBox;
		[Widget("IdentificationBox")]
		protected Gtk.VBox _identificationBox;
		[Widget("IdentificationSpacer")]
		protected Gtk.HBox _identificationSpacer;
		[Widget("VerticalPane")]
		protected Gtk.VPaned _vertical_pane;
		[Widget("InputBox")]
		protected HBox _inputBox;
		[Widget("LeftInputBox")]
		protected HBox _leftInputBox;
		[Widget("MainFrame")]
		protected Frame _mainFrame;
		[Widget("EntryBox")]
		protected VBox _entryBox;
		[Widget("MessageEntryBox")]
		protected VBox _messageEntryBox;
		[Widget ("EntryToolbarBox")]
		protected VBox _entryToolbarBox;
		[Widget("RightInputBox")]
		protected HBox _rightInputBox;
		[Widget("ViewBox")]
		protected HBox _viewBox;
		[Widget("DisplayBox")]
		protected VBox _displayBox;
		[Widget("TopDisplayBox")]
		protected VBox _topDisplayBox;
		[Widget("BottomDisplayBox")]
		protected VBox _bottomDisplayBox;
		[Widget("MainDisplayPane")]
		protected HPaned _mainDisplayPane;
		[Widget("LeftViewBox")]
		protected VBox _leftViewBox;
		[Widget("RightViewBox")]
		protected VBox _rightViewBox;
		[Widget("StatusBox")]
		protected HBox _statusBox;
		[Widget("LeftStatusBox")]
		protected HBox _leftStatusBox;
		[Widget("RightSatusBox")]
		protected HBox _rightStatusBox;
		[Widget("CenterStatusBox")]
		protected HBox _centerStatusBox;
		[Widget("LeftDisplayPaneBox")]
		protected VBox _leftDisplayPaneBox;
		[Widget("RightDisplayPaneBox")]
		protected VBox _rightDisplayPaneBox;
		
		protected Widget _nativeWidget;
		protected IContainerWindow<Widget> _window;
		protected IConversation _conversation;
		
		protected IConfigurationSection _config;
		protected IConfigurationSection _logging_config;
		
		public Widget NativeWidget { get { return _nativeWidget; } }
		public IConversation Conversation { get { return _conversation; } }
		public IContainerWindow<Widget> ContainerWindow { get { return _window; } }
		
		public abstract bool ShowActionToolbar { get; set; }
		public abstract bool ShowInputToolbar { get; set; }
		public abstract bool ShowAccountImage { get; set; }
		public abstract bool ShowContactImage { get; set; }
		public abstract bool ShowPersonalMessage { get; set; }
		public abstract bool ShowTimestamps { get; set; }
		public abstract bool UseDefaultView { get; set; }
		public abstract bool EnableLogging { get; set; }
		public abstract bool EnableSounds { get; set; }
		public abstract bool UseDefaultSettings { get; set; }
		
		public AbstractChatWidget (IContainerWindow<Widget> window, IConversation conversation)
		{
			_window = window;
			_conversation = conversation;
			
			// Load configuration options
			_config = Configuration.Conversation.Section;
			_logging_config = Configuration.Logging.Section;
		}
		
		public virtual void Initialize ()
		{
			// Load the widget from glade resource.
			_nativeWidget = GladeUtility.ExtractWidget<Widget> (GladeUtility.GetGladeResourceStream (typeof (AbstractChatWidget).Assembly, "AbstractChatWidget.glade"), "Widget", this);
		}
		
		public abstract void Destroy ();
		public abstract void SwitchTo();
		public abstract void Focus ();
		public abstract void Update ();
		
		public virtual void Close ()
		{
			_window.RemoveConversation (_conversation, true);
		}
		
		public Gtk.Box GetBox (ChatWidgetPositions position)
		{
			switch (position)
			{
				case ChatWidgetPositions.BottomDisplay:
					return _bottomDisplayBox;
				case ChatWidgetPositions.Identification:
					return _identificationBox;
				case ChatWidgetPositions.LeftDisplayPane:
					return _leftDisplayPaneBox;
				case ChatWidgetPositions.LeftInput:
					return _leftInputBox;
				case ChatWidgetPositions.LeftStatus:
					return _leftStatusBox;
				case ChatWidgetPositions.LeftView:
					return _leftViewBox;
				case ChatWidgetPositions.CenterStatus:
					return _centerStatusBox;
				case ChatWidgetPositions.MessageEntry:
					return _messageEntryBox;
				case ChatWidgetPositions.EntryToolbar:
					return _entryToolbarBox;
				case ChatWidgetPositions.RightDisplayPane:
					return _rightDisplayPaneBox;
				case ChatWidgetPositions.RightInput:
					return _rightInputBox;
				case ChatWidgetPositions.RightStatus:
					return _rightStatusBox;
				case ChatWidgetPositions.RightView:
					return _rightViewBox;
				case ChatWidgetPositions.TopDisplay:
					return _topDisplayBox;
			}
			
			return null;
		}
		
		public void ShowBox (ChatWidgetPositions position)
		{
			Box box = GetBox (position);
			box.Show ();
		}
		
		public void HideBox (ChatWidgetPositions position)
		{
			Box box = GetBox (position);
			box.Hide ();
		}
		
		public void RemoveChatWidget (ChatWidgetPositions position)
		{
			Box box = GetBox (position);
			box.Remove (box.Children[0]);
		}
		
		public void SetChatWidget(ChatWidgetPositions position, Widget widget)
		{
			SetChatWidget (position, widget, true, true, 0);
		}
		
		public virtual void SetChatWidget (ChatWidgetPositions position, Widget widget, bool expand, bool fill, uint padding)
		{
			ThrowUtility.ThrowIfNull ("widget", widget);
			
			Box box = GetBox (position);
			box.PackStart (widget, expand, fill, padding);
			
			widget.ShowAll ();
		}
		
		protected void EmitBecomingActive ()
		{
			if (BecomingActive != null && _window.CurrentWidget != this)
				BecomingActive (this, new EventArgs ());
		}
		
		protected void EmitBecomeActive ()
		{
			if (BecomeActive != null && _window.CurrentWidget != this)
				BecomeActive (this, new EventArgs ());
		}
	}
}